package com.sf.algo;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.io.FileUtils;
import org.springframework.context.ConfigurableApplicationContext;

import com.sf.algo.entity.AI;
import com.sf.algo.entity.Jobs;
import com.sf.algo.entity.Result;
import com.sf.algo.http.HttpUtil;
import com.sf.algo.http.JacksonUtil;
import com.sf.algo.shortpath.Coord;
import com.sf.algo.shortpath.StartEndResult;
import com.sf.algo.solve.domain.Goods;
import com.sf.algo.solve.domain.Location;
import com.sf.algo.solve.domain.Person;
import com.sf.algo.solve.domain.Solution;
import com.sf.algo.solve.solver.DirectionUtils;
import com.sf.algo.solve.solver.Solver;

public class AppUtils {
	
	private static final String HOST = "http://10.2.5.64/";
	private static final String ENV = "test";
	private static final int totalStep = 400;
	private static int stepLimit = totalStep;
	private static final String distanceFile = "d:\\distance.txt";
	
	private static Map<String, StartEndResult> locationMap = new HashMap<>();

	private static final Result init() {
		String url = HOST + ENV;
		Map<String, String> params = new HashMap<>();
		String name = "蚁人团队";
		params.put("name", name);
		return HttpUtil.doPost(url, params, Result.class);
	}
	
	public static Result move(String id,String direction){
		String url = HOST + ENV + "/" + id + "/move";
		Map<String,String> params = new HashMap<>();
		params.put("direction", direction);
		return HttpUtil.doApplicationJson(url, params, Result.class);	
	}
	
	private static final String getCoordStr(Coord coord) {
		return String.format("(%s,%s)", coord.getX(), coord.getY());
	}
	
	public static final void start(ConfigurableApplicationContext context) {
		Result initResult = init();
		System.out.println("map init finish, " + initResult.getId());
//		List<Coord> barList = new ArrayList<>();
//		List<Walls> walls = initResult.getState().getWalls();
//		for (Walls walls2 : walls) {
//			barList.add(new Coord(walls2.getX(), walls2.getY()));
//		}
//		
//		List<Coord> coordList = new ArrayList<>();
//		for (int i=0; i<12; i++) {
//			for (int j=0; j<12; j++) {
//				coordList.add(new Coord(i, j));
//			}
//		}
//		
//		BatchCoordProcessor processor = new BatchCoordProcessor(coordList, barList);
//		List<StartEndResult> distanceList = processor.process();
//		try {
//			FileUtils.write(new File(distanceFile), JacksonUtil.toJSON(distanceList), Charset.forName("UTF-8"));
//		} catch (IOException e) {
//			e.printStackTrace();
//		}
		
		List<StartEndResult> distanceList = null;
		try {
			distanceList = JacksonUtil.toList(FileUtils.readFileToString(new File(AppUtils.class.getResource("/distance.txt").getFile()), "UTF-8"), StartEndResult.class);
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		for (StartEndResult startEndResult : distanceList) {
			locationMap.put(getCoordStr(startEndResult.getStart()) + getCoordStr(startEndResult.getEnd()), 
					startEndResult);
		}
		System.out.println(locationMap.size());
		Result result = initResult;
		long score = 0;
		while (stepLimit != 0) {
			Solution problem = createProblem(result);
			Solver solver = context.getBean(Solver.class);
			Solution bestSolution = solver.solve(problem);

			Location from = bestSolution.getPersonList().get(0).getLocation();
			Location to = bestSolution.getPersonList().get(0).getNext().getLocation();
			
			StartEndResult startEndResult = locationMap.get(from.toString() + to.toString());
			Location nextLocation = new Location(startEndResult.getPath().get(1));
			String direction = DirectionUtils.calcDirection(from, nextLocation);
			System.out.println(String.format("现在位置:%s,下一步位置:%s", from, nextLocation));

			result = move(initResult.getId(), direction);
			score += result.getReward();
			System.out.println(String.format("移动后坐标:%s", result.getState().getAi()));
			System.out.println("第" + (totalStep - stepLimit + 1) + "步,方向:" + direction + ",得分:" + result.getReward() + ",总得分:" + score);
			stepLimit--;
		}
	}
	
	private static Solution createProblem(Result result) {
		Solution problem = new Solution();

		List<Person> personList = new ArrayList<>(1);
		Person p = new Person();
		personList.add(p);
		p.setId(1L);
		AI ai = result.getState().getAi();
		p.setLocation(new Location(ai.getX(), ai.getY()));
		problem.setPersonList(personList);

		List<Goods> goodsList = new ArrayList<>();
		problem.setGoodsList(goodsList);
		List<Jobs> jobs = result.getState().getJobs();
		long goodsId = 1;
		for (int i = 0; i < jobs.size(); i++) {
			Jobs item = jobs.get(i);
			Goods goods = new Goods();
			goods.setId(goodsId++);
			goods.setLocation(new Location(item.getX(), item.getY()));
			goods.setValue(item.getValue());
			goodsList.add(goods);
		}

		problem.setStepLimit(stepLimit);

		return problem;
	}
	
}
